D3.5 Conservation of Momentum#


Motivation — Conservation as a Consequence, Not a New Law#

Conservation of momentum is often presented as a standalone principle.
In reality, it is not a new idea at all.

Momentum conservation is simply a special application of the impulse–momentum theorem applied to a system rather than a single particle.

For a single point particle, conservation of momentum is rarely interesting: any interaction with the surroundings generally transfers momentum to or from the particle, and its momentum changes accordingly. Nothing is “conserved” unless the particle is completely isolated—which is uncommon in practice.

The true power of momentum conservation appears when we shift perspective:

instead of tracking one particle, we track multiple interacting particles together as a system.

In that case, momentum transfers between particles can cancel internally, revealing a quantity that remains unchanged.


D3.5.1 From a Single Particle to a Two-Particle System#

For a single point particle, the impulse–momentum theorem is

\[ j_x = \Delta p_x. \]

Now consider two interacting point particles, labeled particle 1 and particle 2.

Each particle may experience forces due to the other particle, as well as forces due to the surroundings. Their individual momentum changes are

\[ \Delta p_{1,x} = j_{1,x}, \qquad \Delta p_{2,x} = j_{2,x}. \]

D3.5.2 Total Momentum of a System#

We define the total momentum of the two-particle system as the sum of the individual momenta:

\[ P_x = p_{1,x} + p_{2,x}. \]

Here:

  • lowercase \(p_{1,x}\) and \(p_{2,x}\) refer to individual particles,

  • uppercase \(P_x\) refers to the system as a whole.

The change in total momentum is therefore

\[ \Delta P_x = \Delta p_{1,x} + \Delta p_{2,x}. \]

D3.5.3 Internal vs. External Impulses#

Each particle in a system may experience impulses from different sources:

  • Internal impulses: due to forces the particles exert on each other

  • External impulses: due to forces from outside the system (e.g., the ground, air resistance)

When two particles interact, the forces they exert on each other form an action–reaction pair, as described by Newton’s Third Law. These forces are equal in magnitude, opposite in direction, and—crucially—act over the same interaction time.

As a result, the impulses exchanged internally satisfy

\[ j_{1,x}^{(\text{internal})} + j_{2,x}^{(\text{internal})} = 0. \]

Key Consequence of Internal Impulses

Internal impulses always cancel exactly when summed over the system.
Internal interactions may transfer momentum from one particle to another, but they cannot change the total momentum of the system.

Only external impulses—those arising from forces outside the system—can change the system’s total momentum.


Why This Works for Momentum (and Not Always for Energy)#

It is important to recognize why this cancellation works so cleanly for momentum.

Impulse depends on force acting through time.
Because action–reaction forces act over the same time interval, their impulses always cancel at the system level.

This is not generally true for work and energy.

Work depends on force acting through displacement, and interacting particles can move in opposite directions, during the same interaction. As a result, internal action–reaction forces can do work on both particles with the same sign, and internal work does not necessarily cancel.

You do not need to understand this distinction in detail yet—but it is worth keeping in mind.
It explains why momentum conservation follows so directly from Newton’s laws, while energy analysis requires additional care.

This contrast will become important when we later study the work–energy theorem.


D3.5.4 Conservation of Momentum#

If the net external impulse acting on the system is zero,

\[ J_{\text{ext},x} = 0, \]

then the change in total momentum must also be zero:

\[ \Delta P_x = 0. \]

This leads directly to the conservation of momentum.


Conservation of Momentum (1D, Two-Particle System)

If the net external impulse on a system is zero, then the total momentum of the system remains constant:

\[ P_{x,i} = P_{x,f}. \]

For a two-particle system, this means

\[ p_{1,x,i} + p_{2,x,i} = p_{1,x,f} + p_{2,x,f}. \]

Written in terms of mass and velocity, the working equation is

\[ m_1 v_{1,x,i} + m_2 v_{2,x,i} \;=\; m_1 v_{1,x,f} + m_2 v_{2,x,f}. \]

This result is not an assumption—it is a direct consequence of the impulse–momentum theorem applied to a multi-particle system.


Example – Conservation of Momentum in a 1D Collision

Problem
Two carts move along a straight, frictionless track.

  • Cart 1 has mass \(m_1 = 1.0\ \text{kg}\) and initial velocity

    \[ v_{1,x,i} = +4.0\ \text{m/s}. \]
  • Cart 2 has mass \(m_2 = 2.0\ \text{kg}\) and is initially at rest:

    \[ v_{2,x,i} = 0. \]

After the interaction, cart 1 moves with velocity

\[ v_{1,x,f} = +1.0\ \text{m/s}. \]

Assuming external impulses are negligible, find the final velocity of cart 2.


Methodology

  1. Treat both carts together as a two-particle system.

  2. Since the net external impulse is zero, apply conservation of momentum.

  3. Use the working equation and solve for the unknown final velocity.


Solution

Initial total momentum:

\[ P_{x,i} = m_1 v_{1,x,i} + m_2 v_{2,x,i} = (1.0)(4.0) + (2.0)(0) = 4.0\ \text{kg·m/s}. \]

Final total momentum:

\[ P_{x,f} = m_1 v_{1,x,f} + m_2 v_{2,x,f}. \]

Conservation of momentum requires

\[ 4.0 = (1.0)(1.0) + (2.0)\,v_{2,x,f}. \]

Solving for \(v_{2,x,f}\):

\[ 2.0\,v_{2,x,f} = 3.0 \quad\Rightarrow\quad v_{2,x,f} = +1.5\ \text{m/s}. \]

Interpretation

During the interaction, momentum is transferred from cart 1 to cart 2 through internal impulses.
Although the individual momenta change, the total momentum of the two-cart system remains constant.

The lighter cart slows down, while the heavier cart begins moving in the same direction, consistent with momentum conservation.


Box Activity 1 – Conservation of Momentum (Two-Particle System)

In this activity, you will apply conservation of momentum to a simple one-dimensional interaction.
Focus on system-level reasoning and careful use of signs.


Task

Two carts move along a straight, frictionless track.

  • Cart A has mass

    \[ m_A = 1.5\ \text{kg} \]

    and initial velocity

    \[ v_{A,x,i} = +3.0\ \text{m/s}. \]
  • Cart B has mass

    \[ m_B = 1.0\ \text{kg} \]

    and is initially at rest.

After the interaction, cart A moves with velocity

\[ v_{A,x,f} = -1.0\ \text{m/s}. \]
  1. Compute the initial total momentum of the system.

  2. Use conservation of momentum to find the final momentum of cart B.

  3. Determine the final velocity of cart B.

  4. State whether the carts move in the same or opposite directions after the interaction.

Use proper signs throughout.

A Possible Solution Guide

Initial total momentum

\[ P_{x,i} = m_A v_{A,x,i} + m_B v_{B,x,i} = (1.5)(3.0) + (1.0)(0) = +4.5\ \text{kg·m/s}. \]

Final momentum of cart A

\[ p_{A,x,f} = m_A v_{A,x,f} = (1.5)(-1.0) = -1.5\ \text{kg·m/s}. \]

Final momentum of cart B

\[ p_{B,x,f} = P_{x,i} - p_{A,x,f} = 4.5 - (-1.5) = +6.0\ \text{kg·m/s}. \]

Final velocity of cart B

\[ v_{B,x,f} = \frac{p_{B,x,f}}{m_B} = \frac{6.0}{1.0} = +6.0\ \text{m/s}. \]

Interpretation

The carts move in opposite directions after the interaction.
Momentum is redistributed between the carts, while the total system momentum remains constant.

# DIY Cell

Box Activity 2 – Conservation of Momentum Using Python

In this activity, you will use Python to solve a 1D momentum-conservation problem in two ways:

  1. a direct calculator approach, and

  2. a symbolic equation-solver approach using SymPy.


Task

Two carts interact on a frictionless track.

  • Cart 1:

    \[ m_1 = 0.80\ \text{kg}, \qquad v_{1,x,i} = +2.5\ \text{m/s} \]
  • Cart 2:

    \[ m_2 = 1.20\ \text{kg}, \qquad v_{2,x,i} = -1.0\ \text{m/s} \]

After the interaction, cart 1 has velocity

\[ v_{1,x,f} = -0.50\ \text{m/s}. \]

Assuming net external impulse is zero, use momentum conservation to determine \(v_{2,x,f}\).

Print your final answer in scientific notation with three significant figures.

A Possible Solution Guide

Method 1 — Calculator approach (direct computation)

m1 = 0.80
m2 = 1.20
v1_i = 2.5
v2_i = -1.0
v1_f = -0.50

P_i = m1*v1_i + m2*v2_i

v2_f = (P_i - m1*v1_f)/m2

print(f"{v2_f:.3e}")


Method 2 — SymPy equation solver

import sympy as sp

m1 = 0.80
m2 = 1.20
v1_i = 2.5
v2_i = -1.0
v1_f = -0.50

v2_f = sp.symbols('v2_f')

equation = sp.Eq(m1*v1_i + m2*v2_i, m1*v1_f + m2*v2_f)

solution = sp.solve(equation, v2_f)[0]

print(f"{float(solution):.3e}")


Interpretation

The computed value of \(v_{2,x,f}\) ensures that $\( m_1 v_{1,x,i} + m_2 v_{2,x,i} = m_1 v_{1,x,f} + m_2 v_{2,x,f}, \)$ so the total system momentum remains constant.

# DIY Cell

D3.5.5 Why Conservation Works So Well#

Momentum conservation is especially powerful because:

  • internal forces can be complicated or unknown,

  • interaction times may be very short (collisions),

  • external impulses may be negligible over the interaction time.

In such cases, focusing on total momentum before and after the interaction allows us to predict outcomes without knowing the detailed forces involved.

This is why conservation of momentum plays a central role in analyzing:

  • collisions,

  • recoil,

  • explosions,

  • and separation events.

In the next section, we will apply momentum conservation to specific two-particle scenarios and see how momentum is redistributed between particles while the total remains unchanged.


D3.5.6 Two-Particle Simulation#

Interpreting the Collision Simulations#

In general, a collision is an interaction during which particles exert large forces on each other for a short time, transferring momentum between them. These momentum transfers are internal to the system: one particle loses momentum while the other gains momentum. Because the internal impulses are equal in magnitude and opposite in direction, they cannot change the total momentum of the system. As a result, the system’s total momentum remains constant throughout the collision.

In the simulations shown here, we deliberately consider two separate collision scenarios with carefully chosen initial conditions. In the first case, the particles stick together after the collision (perfectly inelastic collision). In the second case, the particles separate after the collision (elastic collision) with one particle initially at rest. These specific setups allow us to determine the final motion using conservation of momentum alone, without invoking any additional principles.

It is important to emphasize that this is not true for all elastic collisions. In the most general elastic collision, both conservation of momentum and kinetic energy must be employed to fully determine the outcome. The additional requirement of kinetic energy conservation will be introduced and explored in the next module. Here, the focus is on seeing how momentum conservation emerges naturally from internal momentum transfer during collisions, and how it provides a powerful and sufficient tool when the physical conditions allow.

Using the Simulations as a Problem-Solving Tool#

The collision simulations in this module are not just demonstrations—they are tools you can actively use. By modifying the initial conditions in the code (masses, initial velocities, and starting positions), you can test your physical reasoning and verify calculations for problems you encounter in homework, quizzes, or exams.

For example, after solving a collision problem analytically using conservation of momentum, you can change the values of m1, m2, v1_0, and v2_0 in the simulation to match the problem setup. Running the simulation allows you to observe how the particles move before and after the interaction and to check whether the final velocities agree with your calculated results. This provides immediate feedback on both your algebra and your sign conventions.

Used in this way, the simulations serve as a sanity check, not a shortcut. They help you build intuition about how momentum is redistributed during collisions and reinforce that internal interactions cannot change total momentum. Over time, experimenting with different initial conditions will strengthen your confidence in applying conservation principles correctly—especially under exam conditions where careful reasoning matters most.

Hide code cell source

%reset -f
%config HistoryManager.enabled = False

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML, display

# -----------------------------------------
# 1D Two-Particle Collision: Perfectly Inelastic
# (They stick together after collision)
# -----------------------------------------

# Parameters (edit as desired)
m1 = 2.0          # kg
m2 = 1.0          # kg

x1_0 = 0.20       # m
x2_0 = 0.80       # m

v1_0 = 1.50       # m/s
v2_0 = -0.50      # m/s

r1 = 0.08         # "visual radius" for collision detection/drawing (m)
r2 = 0.08

t_max = 4.0       # s
dt = 0.01         # s

# Derived
n = int(t_max / dt) + 1
t = np.linspace(0, t_max, n)

# Arrays
x1 = np.zeros(n); x2 = np.zeros(n)
v1 = np.zeros(n); v2 = np.zeros(n)

# Initial conditions
x1[0], x2[0] = x1_0, x2_0
v1[0], v2[0] = v1_0, v2_0

# Initial momentum
p1_i = m1 * v1_0
p2_i = m2 * v2_0
P_i  = p1_i + p2_i

# Collision state
stuck = False
t_collide = None
v_stick = None

# Simulation loop
for i in range(n - 1):
    if not stuck:
        # Update positions
        x1[i+1] = x1[i] + v1[i] * dt
        x2[i+1] = x2[i] + v2[i] * dt
        v1[i+1] = v1[i]
        v2[i+1] = v2[i]

        # Check collision
        if (x1[i+1] + r1) >= (x2[i+1] - r2):
            # Collision time marker
            t_collide = t[i+1]

            # Correct overlap to a shared contact midpoint
            x_mid = 0.5 * ((x1[i+1] + r1) + (x2[i+1] - r2))
            x1[i+1] = x_mid - r1
            x2[i+1] = x_mid + r2

            # Perfectly inelastic collision: common velocity from momentum conservation
            v_stick = (m1*v1[i+1] + m2*v2[i+1]) / (m1 + m2)

            v1[i+1] = v_stick
            v2[i+1] = v_stick
            stuck = True
    else:
        # Once stuck: same velocity, keep separation fixed visually
        v1[i+1] = v_stick
        v2[i+1] = v_stick

        x1[i+1] = x1[i] + v_stick * dt
        x2[i+1] = x2[i] + v_stick * dt

# Final combined quantities
M_f = m1 + m2
v_f = v_stick if v_stick is not None else (m1*v1[-1] + m2*v2[-1]) / (m1 + m2)

p1_f = m1 * v_f
p2_f = m2 * v_f
P_f  = p1_f + p2_f

# Print summary
print("---- Perfectly Inelastic Collision (Stick Together) ----")
print(f"m1 = {m1:.3e} kg,  v1_i = {v1_0:.3e} m/s,  p1_i = {p1_i:.3e} kg·m/s")
print(f"m2 = {m2:.3e} kg,  v2_i = {v2_0:.3e} m/s,  p2_i = {p2_i:.3e} kg·m/s")
print(f"Initial total momentum P_i = {P_i:.3e} kg·m/s")
print("--------------------------------------------------------")
print(f"Final combined mass M_f = {M_f:.3e} kg")
print(f"Final common velocity v_f = {v_f:.3e} m/s")
print(f"p1_f = {p1_f:.3e} kg·m/s,  p2_f = {p2_f:.3e} kg·m/s")
print(f"Final total momentum P_f = {P_f:.3e} kg·m/s")
if t_collide is not None:
    print(f"Collision occurred at t ≈ {t_collide:.3e} s")
else:
    print("No collision occurred within the simulation time.")

# -----------------------------------------
# Animation
# -----------------------------------------
xmin = min(x1.min(), x2.min()) - 0.1
xmax = max(x1.max(), x2.max()) + 0.1

fig, ax = plt.subplots()
ax.set_xlim(xmin, xmax)
ax.set_ylim(-0.15, 0.15)
ax.set_yticks([])
ax.set_xlabel("x (m)")
ax.set_title("1D Perfectly Inelastic Collision (Particles Stick)")

p1_plot, = ax.plot([], [], marker='o', linestyle='', markersize=14, label=f"m1={m1} kg")
p2_plot, = ax.plot([], [], marker='o', linestyle='', markersize=14, label=f"m2={m2} kg")
txt = ax.text(0.02, 0.80, "", transform=ax.transAxes)

ax.legend(loc="upper center", ncol=2, frameon=False)

def init():
    p1_plot.set_data([], [])
    p2_plot.set_data([], [])
    txt.set_text("")
    return p1_plot, p2_plot, txt

def update(frame):
    p1_plot.set_data([x1[frame]], [0.0])
    p2_plot.set_data([x2[frame]], [0.0])

    txt.set_text(
        f"t = {t[frame]:.2f} s\n"
        #f"v1 = {v1[frame]:.2f} m/s,  p1 = {m1*v1[frame]:.2f} kg·m/s\n"
        #f"v2 = {v2[frame]:.2f} m/s,  p2 = {m2*v2[frame]:.2f} kg·m/s\n"
        #f"P = {(m1*v1[frame] + m2*v2[frame]):.2f} kg·m/s"
    )
    return p1_plot, p2_plot, txt

anim = FuncAnimation(fig, update, frames=n, init_func=init, interval=20, blit=True)

plt.close(fig)
display(HTML(anim.to_jshtml()))
---- Perfectly Inelastic Collision (Stick Together) ----
m1 = 2.000e+00 kg,  v1_i = 1.500e+00 m/s,  p1_i = 3.000e+00 kg·m/s
m2 = 1.000e+00 kg,  v2_i = -5.000e-01 m/s,  p2_i = -5.000e-01 kg·m/s
Initial total momentum P_i = 2.500e+00 kg·m/s
--------------------------------------------------------
Final combined mass M_f = 3.000e+00 kg
Final common velocity v_f = 8.333e-01 m/s
p1_f = 1.667e+00 kg·m/s,  p2_f = 8.333e-01 kg·m/s
Final total momentum P_f = 2.500e+00 kg·m/s
Collision occurred at t ≈ 2.200e-01 s

Hide code cell source

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML, display

# ---------------------------------------------------------
# 1D Two-Particle Collision: Perfectly Elastic (m2 at rest)
# After collision they move separately (no sticking)
# ---------------------------------------------------------
# Note: This uses the standard 1D elastic collision update.
# Even though you can solve many versions with one unknown,
# the simulation simply applies the collision rule at contact.

# Parameters (edit as desired)
m1 = 2.0          # kg
m2 = 1.0          # kg

x1_0 = 0.20       # m
x2_0 = 1.80       # m

v1_0 = 1.50       # m/s (moving toward particle 2)
v2_0 = 0.00       # m/s (at rest)

r1 = 0.08         # visual radius (m)
r2 = 0.08

t_max = 4.0       # s
dt = 0.01         # s

# Derived
n = int(t_max / dt) + 1
t = np.linspace(0, t_max, n)

# Arrays
x1 = np.zeros(n); x2 = np.zeros(n)
v1 = np.zeros(n); v2 = np.zeros(n)

# Initial conditions
x1[0], x2[0] = x1_0, x2_0
v1[0], v2[0] = v1_0, v2_0

# Initial momenta
p1_i = m1 * v1_0
p2_i = m2 * v2_0
P_i  = p1_i + p2_i

# Collision control (avoid repeated updates while overlapping)
collided = False
t_collide = None
v1_after = None
v2_after = None

# Simulation loop
for i in range(n - 1):
    # Update positions
    x1[i+1] = x1[i] + v1[i] * dt
    x2[i+1] = x2[i] + v2[i] * dt
    v1[i+1] = v1[i]
    v2[i+1] = v2[i]

    # Collision detection
    if (x1[i+1] + r1) >= (x2[i+1] - r2) and not collided:
        t_collide = t[i+1]

        # Correct overlap to a shared contact midpoint (simple fix)
        x_mid = 0.5 * ((x1[i+1] + r1) + (x2[i+1] - r2))
        x1[i+1] = x_mid - r1
        x2[i+1] = x_mid + r2

        # 1D perfectly elastic collision formulas
        u1, u2 = v1[i+1], v2[i+1]
        v1_new = ((m1 - m2) / (m1 + m2)) * u1 + (2 * m2 / (m1 + m2)) * u2
        v2_new = (2 * m1 / (m1 + m2)) * u1 + ((m2 - m1) / (m1 + m2)) * u2

        v1[i+1] = v1_new
        v2[i+1] = v2_new

        v1_after = v1_new
        v2_after = v2_new

        collided = True

    # Reset collision flag once they are separated (so only one collision event)
    if (x1[i+1] + r1) < (x2[i+1] - r2):
        collided = False

# Final values (end of sim)
v1_f = v1[-1]
v2_f = v2[-1]
p1_f = m1 * v1_f
p2_f = m2 * v2_f
P_f  = p1_f + p2_f

# Print summary (scientific notation)
print("---- Perfectly Elastic Collision (m2 initially at rest) ----")
print(f"m1 = {m1:.3e} kg,  v1_i = {v1_0:.3e} m/s,  p1_i = {p1_i:.3e} kg·m/s")
print(f"m2 = {m2:.3e} kg,  v2_i = {v2_0:.3e} m/s,  p2_i = {p2_i:.3e} kg·m/s")
print(f"Initial total momentum P_i = {P_i:.3e} kg·m/s")
print("-----------------------------------------------------------")
if t_collide is not None:
    print(f"Collision occurred at t ≈ {t_collide:.3e} s")
    print(f"Immediately after collision: v1 = {v1_after:.3e} m/s, v2 = {v2_after:.3e} m/s")
else:
    print("No collision occurred within the simulation time.")
print("-----------------------------------------------------------")
print(f"End-of-sim velocities: v1_f = {v1_f:.3e} m/s,  v2_f = {v2_f:.3e} m/s")
print(f"End-of-sim momenta:   p1_f = {p1_f:.3e} kg·m/s, p2_f = {p2_f:.3e} kg·m/s")
print(f"Final total momentum  P_f  = {P_f:.3e} kg·m/s")

# -----------------------------------------
# Animation
# -----------------------------------------
xmin = min(x1.min(), x2.min()) - 0.1
xmax = max(x1.max(), x2.max()) + 0.1

fig, ax = plt.subplots()
ax.set_xlim(xmin, xmax)
ax.set_ylim(-0.15, 0.15)
ax.set_yticks([])
ax.set_xlabel("x (m)")
ax.set_title("1D Perfectly Elastic Collision (m2 initially at rest)")

p1_plot, = ax.plot([], [], marker='o', linestyle='', markersize=14, label=f"m1={m1} kg")
p2_plot, = ax.plot([], [], marker='o', linestyle='', markersize=14, label=f"m2={m2} kg")
txt = ax.text(0.02, 0.80, "", transform=ax.transAxes)

ax.legend(loc="upper center", ncol=2, frameon=False)

def init():
    p1_plot.set_data([], [])
    p2_plot.set_data([], [])
    txt.set_text("")
    return p1_plot, p2_plot, txt

def update(frame):
    p1_plot.set_data([x1[frame]], [0.0])
    p2_plot.set_data([x2[frame]], [0.0])

    txt.set_text(
        f"t = {t[frame]:.2f} s\n"
        #f"v1 = {v1[frame]:.2f} m/s,  p1 = {m1*v1[frame]:.2f} kg·m/s\n"
        #f"v2 = {v2[frame]:.2f} m/s,  p2 = {m2*v2[frame]:.2f} kg·m/s\n"
        #f"P  = {(m1*v1[frame] + m2*v2[frame]):.2f} kg·m/s"
    )
    return p1_plot, p2_plot, txt

anim = FuncAnimation(fig, update, frames=n, init_func=init, interval=20, blit=True)

plt.close(fig)
display(HTML(anim.to_jshtml()))
---- Perfectly Elastic Collision (m2 initially at rest) ----
m1 = 2.000e+00 kg,  v1_i = 1.500e+00 m/s,  p1_i = 3.000e+00 kg·m/s
m2 = 1.000e+00 kg,  v2_i = 0.000e+00 m/s,  p2_i = 0.000e+00 kg·m/s
Initial total momentum P_i = 3.000e+00 kg·m/s
-----------------------------------------------------------
Collision occurred at t ≈ 9.700e-01 s
Immediately after collision: v1 = 5.000e-01 m/s, v2 = 2.000e+00 m/s
-----------------------------------------------------------
End-of-sim velocities: v1_f = 5.000e-01 m/s,  v2_f = 2.000e+00 m/s
End-of-sim momenta:   p1_f = 1.000e+00 kg·m/s, p2_f = 2.000e+00 kg·m/s
Final total momentum  P_f  = 3.000e+00 kg·m/s